package user

import (
	"context"
	"strconv"
	"strings"

	"mall/common/moneyx"
	"mall/common/resultx"
	"mall/common/utils/pointy"
	utilx "mall/common/utils/user"
	"mall/service/user/model"
	"mall/service/user/rpc/internal/svc"
	"mall/service/user/rpc/types/user"

	"github.com/zeromicro/go-zero/core/logx"
)

type GetUserAuthByUserIdLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewGetUserAuthByUserIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserAuthByUserIdLogic {
	return &GetUserAuthByUserIdLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *GetUserAuthByUserIdLogic) GetUserAuthByUserId(in *user.GetUserAuthByUserIdReq) (*user.TmpUserAuthInfo, error) {
	if in.UserId == nil || *in.UserId == 0 {
		return nil, resultx.StatusError(resultx.USER_ID_REQUIRED, "")
	}

	var platformId uint32
	if in.PlatformId != nil && *in.PlatformId > 0 {
		platformId = *in.PlatformId
	} else if in.AuthType != nil && len(strings.TrimSpace(*in.AuthType)) > 0 {
		platformId = utilx.GetThirdPartyPlatformId(strings.TrimSpace(*in.AuthType))
	}

	if platformId == 0 {
		return nil, resultx.StatusError(resultx.USER_AUTH_PARAM_INVALID, "")
	}

	// 查询用户是否存在
	filterMap := make(map[string]map[string][]any)
	filterMap[model.UserAuthColumns.PlatformID] = map[string][]any{
		"equalTo": {platformId},
	}
	filterMap[model.UserAuthColumns.UserID] = map[string][]any{
		"equalTo": {*in.UserId},
	}
	selectCols := []string{
		model.UserAuthColumns.UserID,
		model.UserAuthColumns.PlatformID,
		model.UserAuthColumns.Unionid,
		model.UserAuthColumns.Openid,
		model.UserAuthColumns.Nickname,
		model.UserAuthColumns.Avatar,
		model.UserAuthColumns.Status,
	}
	authList, _, err := l.svcCtx.CurrentUser.GetAuthList(l.ctx, model.M{
		"pageSize": uint64(1),
		"select":   strings.Join(selectCols, ","),
	}, -1, filterMap)
	if err != nil {
		return nil, err
	}

	if len(authList) == 0 {
		return &user.TmpUserAuthInfo{}, nil
	}

	userAuth := authList[0]
	resp := &user.TmpUserAuthInfo{
		UserId:     &userAuth.UserID,
		PlatformId: pointy.GetPointer(uint32(userAuth.PlatformID)),
		Openid:     &userAuth.Openid,
		Unionid:    &userAuth.Unionid,
		Nickname:   &userAuth.Nickname,
		Avatar:     &userAuth.Avatar,
		Status:     pointy.GetPointer(uint32(userAuth.Status)),
		UserUUID:   pointy.GetPointer(strconv.FormatUint(userAuth.UserID, 10)),
	}

	if (in.WithRank != nil && *in.WithRank > 0) || (in.WithPoint != nil && *in.WithPoint > 0) ||
		(in.WithBalance != nil && *in.WithBalance > 0) {
		accountFilterMap := make(map[string]map[string][]any)
		accountFilterMap[model.UserAccountColumns.UserID] = map[string][]any{
			"equalTo": {userAuth.UserID},
		}
		accountList, _, err := l.svcCtx.CurrentUser.GetAccountList(l.ctx, model.M{
			"pageSize": uint64(1),
		}, -1, accountFilterMap)
		if err != nil {
			return nil, err
		}

		if len(accountList) == 0 {
			return resp, nil
		}

		userAccount := accountList[0]
		if in.WithRank != nil && *in.WithRank > 0 {
			resp.RankId = pointy.GetPointer(uint32(userAccount.RankID))
		}

		if in.WithPoint != nil && *in.WithPoint > 0 {
			var availablePoint uint64
			if userAccount.Point > 0 {
				availablePoint = uint64(userAccount.Point)
				if availablePoint > userAccount.FrozenPoint {
					availablePoint -= userAccount.FrozenPoint
				} else {
					availablePoint = 0
				}
			}
			resp.AvailablePoint = pointy.GetPointer(availablePoint)
			resp.HistoryPoint = pointy.GetPointer(userAccount.HistoryPoint)
		}

		if in.WithBalance != nil && *in.WithBalance > 0 {
			var availableBalance uint64
			if userAccount.Balance > 0 {
				availableBalance = uint64(userAccount.Balance)
				if availableBalance > userAccount.FrozenBalance {
					availableBalance -= userAccount.FrozenBalance
				} else {
					availableBalance = 0
				}
			}
			resp.AvailableBalance = pointy.GetPointer(moneyx.FormatGem(int64(availableBalance)))
		}
	}

	if in.WithRole != nil && *in.WithRole > 0 {
		detailFilterMap := make(map[string]map[string][]any)
		detailFilterMap[model.UserAccountColumns.UserID] = map[string][]any{
			"equalTo": {userAuth.UserID},
		}
		detailList, _, err := l.svcCtx.CurrentUser.GetDetailList(l.ctx, model.M{
			"pageSize": uint64(1),
		}, -1, detailFilterMap)
		if err != nil {
			return nil, err
		}

		if len(detailList) == 0 {
			return resp, nil
		}

		resp.RoleId = pointy.GetPointer(uint32(detailList[0].Role))
	}

	return resp, nil
}
